package com.rede.didiok.community.service.impl;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.conf.base.BaseSQLConf;
import com.rede.didiok.common.constant.conf.base.BaseSysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.convert.AggEsDocConvert;
import com.rede.didiok.common.domainEvent.EventAction;
import com.rede.didiok.common.dto.admin.AdminDto;
import com.rede.didiok.common.dto.community.MomentCommentDto;
import com.rede.didiok.common.dto.community.UserMomentDto;
import com.rede.didiok.common.dto.community.UserMomentTopicDto;
import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.enums.*;
import com.rede.didiok.common.exception.exceptionType.DeleteException;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.feign.AdminFeignClient;
import com.rede.didiok.common.feign.SearchFeignClient;
import com.rede.didiok.common.feign.UserFeignClient;
import com.rede.didiok.common.holder.RequestHolder;
import com.rede.didiok.common.schema.AggEsDoc;
import com.rede.didiok.common.service.CommonService;
import com.rede.didiok.common.utils.*;
import com.rede.didiok.common.utils.business.DomainEventUtil;
import com.rede.didiok.common.utils.business.FileFeignUtil;
import com.rede.didiok.common.utils.business.SensitiveUtils;
import com.rede.didiok.common.utils.business.UserUtil;
import com.rede.didiok.community.dao.UserMomentDao;
import com.rede.didiok.community.entity.MomentCommentEntity;
import com.rede.didiok.community.entity.UserMomentEntity;
import com.rede.didiok.community.entity.UserMomentTopicEntity;
import com.rede.didiok.community.service.CommunityPraiseRecordService;
import com.rede.didiok.community.service.MomentCommentService;
import com.rede.didiok.community.service.UserMomentService;
import com.rede.didiok.community.service.UserMomentTopicService;

@Slf4j
@Service("userMomentService")
public class UserMomentServiceImpl extends ServiceImpl<UserMomentDao, UserMomentEntity> implements UserMomentService {

    @Resource
    UserMomentService userMomentService;
    @Resource
    MomentCommentService momentCommentService;
    @Resource
    UserMomentTopicService userMomentTopicService;
    @Resource
    CommonService commonService;
    @Resource
    FileFeignUtil fileFeignUtil;
    @Resource
    CommunityPraiseRecordService communityPraiseRecordService;
    @Resource
    private SearchFeignClient searchFeignClient;
    @Resource
    UserFeignClient userFeignClient;
    @Resource
    AdminFeignClient adminFeignClient;
    @Resource
    RedisUtil redisUtil;
    @Resource
    UserUtil userUtil;
    @Autowired
    private SensitiveUtils sensitiveUtils;
    @Resource
    UserMomentDao userMomentDao;
    @Resource
    ApplicationContext context;
    @Resource
    private DomainEventUtil domainEventUtil;

    /***************************** admin:start **************************/
    // region  didiok-admin

    /**
     * 构建动态索引
     *
     * @return
     */
    public String buildMomentAggDoc() {
        long pageSize = 20L;
        long currentPage = 1L;
        UserMomentDto userMomentDto = new UserMomentDto();
        int successCount = 0;
        int failCount = 0;
        while (true) {
            userMomentDto.setCurrentPage(currentPage);
            userMomentDto.setPageSize(pageSize);
            userMomentDto.setAuditStatus(AuditStatusEnum.AGREE);
            userMomentDto.setIsPublish(PublishEnum.PUBLISH);
            IPage<UserMomentEntity> iPage = this.getPageList(userMomentDto);
            List<UserMomentEntity> userMomentList = iPage.getRecords();
            if (userMomentList.size() == 0) {
                break;
            }
            List<AggEsDoc> aggEsDocList = new ArrayList<>();
            for (UserMomentEntity userMoment : userMomentList) {

                UserMomentDto momentDto = new UserMomentDto();
                BeanUtils.copyProperties(userMoment,momentDto);
                AggEsDoc aggEsDoc = AggEsDocConvert.convertMoment(momentDto);
                aggEsDocList.add(aggEsDoc);
            }
            // 同步索引
            String result = searchFeignClient.batchCreateEsIndex(aggEsDocList);
            if (WebUtils.checkSuccess(result)) {
                successCount += userMomentList.size();
            } else {
                failCount += userMomentList.size();
            }
            log.info(result);
            currentPage++;
        }
        return String.format("同步索引执行完成，成功：%s 条，失败：%s 条", successCount, failCount);
    }

    @Override
    public IPage<UserMomentEntity> getPageList(UserMomentDto userMomentDto) {
//        QueryWrapper<UserMomentEntity> queryWrapper = new QueryWrapper<>();
        // 组装查询条件
        UserMomentDto queryObject = new UserMomentDto();
        /**
         * 关键词
         */
        if (StringUtils.isNotEmpty(userMomentDto.getKeyword()) && StringUtils.isNotEmpty(userMomentDto.getKeyword().trim())) {
            queryObject.setKeyword(userMomentDto.getKeyword().trim());
        }

        /**
         * 是否发布
         */
//        if (userMomentDto.getIsPublish() != null) {
//            queryWrapper.eq(SQLConf.IS_PUBLISH, userMomentDto.getIsPublish());
//        }
        /**
         * 是否后台传入
         */
        if (userMomentDto.getIsBack() == null) {
            queryObject.setIsPublish(PublishEnum.PUBLISH);
            queryObject.setAuditStatus(AuditStatusEnum.AGREE);
        }

        /**
         * 指定动态uid
         */
        if (StringUtils.isNotEmpty(userMomentDto.getUid())) {
            queryObject.setUid(userMomentDto.getUid());
        }

        /**
         * 指定用户id
         */
        if (StringUtils.isNotEmpty(userMomentDto.getCreateUserUid())) {
            queryObject.setCreateUserUid(userMomentDto.getCreateUserUid());
        }
//
//        /**
//         * 话题uid
//         */
//        if (StringUtils.isNotEmpty(userMomentDto.getTopicUid())) {
//            queryObject.setTopicUid(userMomentDto.getTopicUid());
//        }

        /**
         * 话题uid
         */
        if (StringUtils.isNotEmpty(userMomentDto.getTopicUids())) {
            queryObject.setTopicUidsLike(userMomentDto.getTopicUids());
        }
        // 获取用户是否登录
        String userUid = RequestHolder.getUserUid();
        // 判断是否只查看关注用户的文章
        if (StringUtils.isNotEmpty(userMomentDto.getOrderBy()) && SysConf.USER_WATCH.equals(userMomentDto.getOrderBy())) {

            if (StringUtils.isNotEmpty(userUid)) {
                R result = userFeignClient.listUserWatchIdsByUserUid(userUid);
                // 获取用户关注的用户
                List<String> toUserUidList = new ArrayList<>();
                if (result.getCode() == 0) {
                    toUserUidList = result.getData(new TypeReference<List<String>>(){});
                }else {
                    throw new FeignException("feign调用异常（获取用户关注的用户）：失败");
                }
                if (toUserUidList.size() > 0) {
                    queryObject.setCreateUserUidIn(toUserUidList);
                } else {
                    IPage<UserMomentEntity> emptyPage = new Page<>();
                    return emptyPage;
                }
            }
        }
        queryObject.setStatus(StatusEnum.ENABLE);

        // 判断是否需要排序
        if (StringUtils.isNotEmpty(userMomentDto.getOrderByAscColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(userMomentDto.getOrderByAscColumn())).toString();
            queryObject.setOrderBy(column + " asc");
        } else if (StringUtils.isNotEmpty(userMomentDto.getOrderByDescColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(userMomentDto.getOrderByDescColumn())).toString();
            queryObject.setOrderBy(column + " desc");
        }else {
            queryObject.setOrderBy(SQLConf.CREATE_TIME + " desc");
        }



        Page<UserMomentEntity> page = new Page<>();
        page.setCurrent(userMomentDto.getCurrentPage());
        page.setSize(userMomentDto.getPageSize());
        // 自定义查询语句
        IPage<UserMomentEntity> pageList = userMomentService.queryPage(page, queryObject);
        List<UserMomentEntity> list = pageList.getRecords();

        List<String> fileUidList = new ArrayList<>();
        List<String> userUidList = new ArrayList<>();
        List<String> momentTopicUidList = new ArrayList<>();
        List<String> businessUidList = new ArrayList<>();
        list.forEach(item -> {
            if(null != item.getCreateUserUid() && item.getCreateUserUid().equals(userUid)){
                item.setMyOwn(YesOrNoEnum.YES.getCode());
            }
            item.setManage(YesOrNoEnum.NO.getCode());
            if (StringUtils.isNotEmpty(item.getFileUids())) {
                String[] array = StringUtils.split(item.getFileUids(), Constants.SYMBOL_COMMA);
                for (int i = 0; i < array.length; i++) {
                    fileUidList.add(array[i]);
                }
            }
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                userUidList.add(item.getCreateUserUid());
            }
            if (StringUtils.isNotEmpty(item.getTopicUids())) {
                List<String> topics = StringUtils.split(item.getTopicUids());
                momentTopicUidList.addAll(topics);
            }
            businessUidList.add(item.getUid());
        });

        // 获取用户列表
        List<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R result = userFeignClient.listUserByUids(userUidList);

            if (result.getCode()==0) {
                userList = result.getData(new TypeReference<List<UserDto>>(){});
            }
            userList.forEach(item->{
                if (StringUtils.isNotEmpty(item.getAvatar())) {
                    fileUidList.add(item.getAvatar());
                }
                if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                    fileUidList.add(item.getBackgroundFileUid());
                }
            });
            // 设置头像
//            userService.setUserAvatar(userList);

        }

        // 获取topic
        Map<String, UserMomentTopicEntity> topicMap = new HashMap<>();
        if (momentTopicUidList.size() > 0) {
            Collection<UserMomentTopicEntity> collection = userMomentTopicService.listByIds(momentTopicUidList);
            for (UserMomentTopicEntity userMomentTopic : collection) {
                topicMap.put(userMomentTopic.getUid(), userMomentTopic);
            }
        }

        // 获取评论
        MomentCommentDto momentCommentDto = new MomentCommentDto();
        momentCommentDto.setSource(CommentSourceEnum.USER_MOMENT.getCode());
        momentCommentDto.setBusinessUidList(businessUidList);
        Map<String, List<MomentCommentEntity>> commentListMap = momentCommentService.getCommentMapByBusinessId(momentCommentDto);

        // 获取图片
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);
        //
        // 设置用户头像和背景图
        for (UserDto item : userList) {
            //获取头像
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getAvatar(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();
                pictureUidsTemp.forEach(picture -> {
                    if (pictureMap.get(picture) != null && pictureMap.get(picture) != "") {
                        pictureListTemp.add(pictureMap.get(picture));
                    }
                });
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                }
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                item.setBackgroundFileUrl(pictureMap.get(item.getBackgroundFileUid()));
            }
        }
        // 过滤敏感信息
        List<UserDto> resultUserList = new ArrayList<>();
        userList.forEach(item -> {
            resultUserList.add(convertUser(item));
        });

        Map<String, UserDto> userMap = resultUserList.stream().collect(
                Collectors.toMap(UserDto::getUid, v->v, (v1,v2)->v2));


        for (UserMomentEntity item : list) {
            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUids())) {
                String[] array = StringUtils.split(item.getFileUids(), Constants.SYMBOL_COMMA);
                List<String> photoList = new ArrayList<>();
                for (int i = 0; i < array.length; i++) {
                    photoList.add(pictureMap.get(array[i]));
                }
                item.setPhotoList(photoList);
            }
            // 设置用户
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                item.setUser(userMap.get(item.getCreateUserUid()));
            }
            // 设置话题
            if (StringUtils.isNotEmpty(item.getTopicUids())) {
                List<String> topics = StringUtils.split(item.getTopicUids());
                List<UserMomentTopicEntity> userMomentTopicList = new ArrayList<>();
                for (String topicUid : topics) {
                    if (topicMap.get(topicUid) != null) {
                        userMomentTopicList.add(topicMap.get(topicUid));
                    }
                }
                item.setUserMomentTopicList(userMomentTopicList);
            }
            // 设置动态下的回复
            if (commentListMap.get(item.getUid()) != null) {
                item.setCommentList(commentListMap.get(item.getUid()));
            }
//
//            // 设置点赞相关信息
//            CommunityPraiseRecordDto userPraiseRecordVO = new CommunityPraiseRecordDto();
//            userPraiseRecordVO.setResourceUid(item.getUid());
//            userPraiseRecordVO.setResourceType(ResourceTypeEnum.MOMENT.getType());
//            Map<String, Object> praiseMap = communityPraiseRecordService.praisedCount(userPraiseRecordVO);
//            item.setPraiseInfo(praiseMap);
//
//            // 获取点赞的用户列表
//            List<UserDto> praiseUserList = communityPraiseRecordService.getPraiseList(userPraiseRecordVO);
//            item.setPraiseUserList(praiseUserList);
//
//            // 设置收藏相关信息
//            CollectDto collectVO = new CollectDto();
//            collectVO.setBizUid(item.getUid());
//            collectVO.setCollectType(ResourceTypeEnum.MOMENT.getType());
//            Map<String, Object> collectInfo = collectService.getCollectCount(collectVO);
//            item.setCollectInfo(collectInfo);

        }
//        pageList.setRecords(list);
        return pageList;
    }


    @Override
    public String addUserMoment(UserMomentDto userMomentDto) {
        HttpServletRequest request = RequestHolder.getRequest();
        // 判断账号是否被禁用
        String userUid = RequestHolder.getUserUid();
        R result = userFeignClient.getUserById(userUid);
        UserDto user;
        if(result.getCode()==0){
            user = result.getData(new TypeReference<UserDto>(){});
        }else {
            // 异常信息
            throw new FeignException("feign调用异常（根据用户id找用户）：失败啦");
        }
        // 判断该用户是否被禁言
        if (user == null || user.getCommentStatus() == SysConf.ZERO) {
            return ResultUtil.errorWithMessage("暂时没有权限发表动态");
        }
        // 判断是否发送过多无意义内容
        String jsonResult = redisUtil.get(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid);
        if (!StringUtils.isEmpty(jsonResult)) {
            Integer count = Integer.valueOf(jsonResult);
            if (count >= Constants.NUM_FIVE) {
                return ResultUtil.errorWithMessage("由于发送过多无意义动态，您已被禁言一小时，请稍后在试~");
            }
        }
        // 判断当前发布内容是否需要审核
        String content = userMomentDto.getContent();
        Integer auditType = commonService.checkIsAudit(request, content);
        boolean flg = true;
        if (auditType.equals(AuditStatusEnum.AGREE)) {
            flg = false;
        }
        // 判断是否垃圾内容
        Map<String, String> sensitiveMap = sensitiveUtils.filter(content, false, SysConf.SYS_SENSITIVE_WORD);
        if (Integer.parseInt(sensitiveMap.get(SysConf.COUNT)) > Constants.NUM_ZERO) {
            if (StringUtils.isEmpty(jsonResult)) {
                Integer count = 0;
                redisUtil.setEx(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid, count.toString(), 1, TimeUnit.HOURS);
            } else {
                redisUtil.incrBy(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid, 1);
            }
            userMomentDto.setContent(sensitiveMap.get(SysConf.CONTENT));
        }

        String convertContent = "";
        if (SensitiveUtils.REPLACEMENT.equals(userMomentDto.getContent())) {
            convertContent = userMomentDto.getContent();
        } else {
            // 将Markdown转换成html
            convertContent = FileUtils.markdownToHtml(userMomentDto.getContent());
        }

        UserMomentEntity userMoment = new UserMomentEntity();
        BeanUtil.copyProperties(userMomentDto, userMoment, SysConf.STATUS);
        userMoment.setCreateUserUid(userUid);
        userMoment.setContent(convertContent);
        userMoment.setIsPublish(PublishEnum.PUBLISH); // 设置上架
        //TODO 目前动态暂不开启审核要求，只要发表即可获取积分
        if (!flg) {
            userMoment.setAuditName("系统");
            userMoment.setAuditTime(new Date());
            userMoment.setAuditStatus(Integer.valueOf(AuditStatusEnum.AGREE));
        } else {
            userMomentDto.setAuditStatus(AuditStatusEnum.WAIT);
        }
        boolean isSave = userMoment.insert();

        // 发送变更请求
        if (isSave) {
            UserMomentDto dto = new UserMomentDto();
            BeanUtils.copyProperties(userMoment, dto);
            domainEventUtil.publishEvent(EventAction.MOMENT_ADD, dto);
        }

        if (!flg) {
            return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
        } else {
            return ResultUtil.successWithMessage(MessageConf.SUBMIT_SUCCESS_AUDIT);
        }

    }

    @Override
    public String editUserMoment(UserMomentDto userMomentDto) {
        UserMomentEntity userMoment = userMomentService.getById(userMomentDto.getUid());
        String userUid = RequestHolder.getUserUid();
        if (userUid != null && !userUid.equals(userMoment.getCommunityUid())) {
            throw new DeleteException("仅能编辑自己发表的动态");
        }
        // 插入数据【使用Spring工具类提供的深拷贝】
        BeanUtils.copyProperties(userMomentDto, userMoment, SysConf.STATUS, SysConf.UID, SysConf.USER_UID);
        userMoment.setUpdateTime(new Date());
        boolean isSave = userMoment.updateById();
        // 发送变更请求
        if (isSave) {
            UserMomentDto dto = new UserMomentDto();
            BeanUtils.copyProperties(userMoment, dto);
            domainEventUtil.publishEvent(EventAction.MOMENT_EDIT, dto);
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String deleteBatchUserMoment(List<UserMomentDto> userMomentVOList) {
        if (userMomentVOList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        String userUid = RequestHolder.getUserUid();

        List<String> uids = new ArrayList<>();
        userMomentVOList.forEach(item -> {
            uids.add(item.getUid());
        });

        Collection<UserMomentEntity> userMoments = userMomentService.listByIds(uids);

        for (UserMomentEntity userMoment : userMoments) {
            if (userUid != null && !userUid.equals(userMoment.getCreateUserUid())) {
                throw new DeleteException("仅能删除自己发表的动态");
            }
            userMoment.setUpdateTime(new Date());
            userMoment.setStatus(StatusEnum.DISABLED);
        }

        userMoments.forEach(item -> {
            item.setUpdateTime(new Date());
            item.setStatus(StatusEnum.DISABLED);
        });
        Boolean isSuccess = userMomentService.updateBatchById(userMoments);

        if (isSuccess) {
            userMoments.forEach(userMoment -> {
                // 发送变更请求
                UserMomentDto dto = new UserMomentDto();
                BeanUtils.copyProperties(userMoment, dto);
                domainEventUtil.publishEvent(EventAction.MOMENT_DELETE, dto);
            });
        }

        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    /**
     * 审批动态
     *
     * @param userMomentDto
     * @return
     */
    @Override
    public String auditMoment(UserMomentDto userMomentDto) {
        UserMomentEntity userMoment = getById(userMomentDto.getUid());
        R adminResult = adminFeignClient.getAdminByUid(RequestHolder.getAdminUid());
        AdminDto admin = null;
        if (adminResult.getCode() == 0) {
            admin = adminResult.getData(new TypeReference<AdminDto>(){});
        }else {
            throw new FeignException("feign调用异常（通过 id 获取管理员）：失败");
        }

        userMoment.setAuditStatus(userMomentDto.getAuditStatus());
        userMoment.setRejectReason(userMomentDto.getRejectReason());
        userMoment.setAuditName(admin.getNickname());
        userMoment.setAuditTime(new Date());
        if (AuditStatusEnum.WAIT.equals(userMomentDto.getAuditStatus()) || AuditStatusEnum.REJECT.equals(userMomentDto.getAuditStatus())) {
            userMoment.setIsPublish(PublishEnum.NO_PUBLISH);
        } else {
            userMoment.setIsPublish(PublishEnum.PUBLISH);
        }
        boolean isSave = userMomentService.updateById(userMoment);
        if (isSave) {
            // 发送变更请求
            UserMomentDto dto = new UserMomentDto();
            BeanUtils.copyProperties(userMoment, dto);
            domainEventUtil.publishEvent(EventAction.MOMENT_AUDIT, dto);
        }
        return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
    }

    // endregion
    /***************************** admin:end **************************/



    /***************************** web:start **************************/
    // region didiok-web

    @Override
    public Page<UserMomentDto> list(UserMomentDto userMomentDto) {
        List<String> toUserUidList = new ArrayList<>();
        // 判断是否只查看关注用户的文章
        if (StringUtils.isNotEmpty(userMomentDto.getOrderBy()) && SysConf.USER_WATCH.equals(userMomentDto.getOrderBy())) {
            // 获取用户是否登录
            String userUid = RequestHolder.getUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                // 获取用户关注的用户
                R result = userFeignClient.listUserWatchIdsByUserUid(userUid);
                if (result.getCode()==0) {
                    toUserUidList = result.getData(new TypeReference<List<String>>(){});
                }else {
                    throw new FeignException("feign调用异常（获取用户关注的用户）：失败");
                }
            }
        }

        Page<UserMomentDto> page = new Page<>(userMomentDto.getCurrentPage(), userMomentDto.getPageSize());
        Page<UserMomentDto> momentDtoPage = userMomentDao.list(page, userMomentDto, toUserUidList);
        List<UserMomentDto> list = momentDtoPage.getRecords();
        /**
         * 文件集合
         */
        List<String> fileUidList = new ArrayList<>();
        List<String> userUidList = new ArrayList<>();
        List<String> momentTopicUidList = new ArrayList<>();
        List<String> businessUidList = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUids())) {
                String[] array = StringUtils.split(item.getFileUids(), Constants.SYMBOL_COMMA);
                for (int i = 0; i < array.length; i++) {
                    fileUidList.add(array[i]);
                }
            }
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                userUidList.add(item.getCreateUserUid());
            }
            if (StringUtils.isNotEmpty(item.getTopicUids())) {
                List<String> topics = StringUtils.split(item.getTopicUids());
                momentTopicUidList.addAll(topics);
            }
            businessUidList.add(item.getUid());
        });

        // 获取用户列表
        List<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R result = userFeignClient.listUserByUids(userUidList);

            if (result.getCode()==0) {
                userList = result.getData(new TypeReference<List<UserDto>>(){});
            }
            userList.forEach(item->{
                if (StringUtils.isNotEmpty(item.getAvatar())) {
                    fileUidList.add(item.getAvatar());
                }
                if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                    fileUidList.add(item.getBackgroundFileUid());
                }
            });
            // 设置头像
//            userService.setUserAvatar(userList);

        }

        // 获取图片
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);
// 设置用户头像和背景图
        for (UserDto item : userList) {
            //获取头像
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getAvatar(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();
                pictureUidsTemp.forEach(picture -> {
                    if (pictureMap.get(picture) != null && pictureMap.get(picture) != "") {
                        pictureListTemp.add(pictureMap.get(picture));
                    }
                });
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                }
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                item.setBackgroundFileUrl(pictureMap.get(item.getBackgroundFileUid()));
            }
        }
        // 过滤敏感信息
        List<UserDto> resultUserList = new ArrayList<>();
        userList.forEach(item -> {
            resultUserList.add(convertUser(item));
        });
        Map<String, UserDto> userMap = resultUserList.stream().collect(
                Collectors.toMap(UserDto::getUid, v->v, (v1,v2)->v2));

        // 获取topic
        Map<String, UserMomentTopicDto> topicMap = new HashMap<>();
        if (momentTopicUidList.size() > 0) {
            Collection<UserMomentTopicEntity> collection = userMomentTopicService.listByIds(momentTopicUidList);
            for (UserMomentTopicEntity userMomentTopic : collection) {
                UserMomentTopicDto userMomentTopicDto = new UserMomentTopicDto();
                BeanUtils.copyProperties(userMomentTopic, userMomentTopicDto);
                topicMap.put(userMomentTopic.getUid(), userMomentTopicDto);
            }
        }
        for (UserMomentDto item : list) {
            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUids())) {
                String[] array = StringUtils.split(item.getFileUids(), Constants.SYMBOL_COMMA);
                List<String> photoList = new ArrayList<>();
                for (int i = 0; i < array.length; i++) {
                    photoList.add(pictureMap.get(array[i]));
                }
                item.setPhotoList(photoList);
            }
            // 设置用户
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                item.setUser(userMap.get(item.getCreateUserUid()));
            }
            // 设置话题
            if (StringUtils.isNotEmpty(item.getTopicUids())) {
                List<String> topics = StringUtils.split(item.getTopicUids());
                List<UserMomentTopicDto> userMomentTopicList = new ArrayList<>();
                for (String topicUid : topics) {
                    if (topicMap.get(topicUid) != null) {
                        userMomentTopicList.add(topicMap.get(topicUid));
                    }
                }
                item.setUserMomentTopicList(userMomentTopicList);
            }

//            // 设置点赞相关信息
//            UserPraiseRecordDto userPraiseRecordVO = new UserPraiseRecordDto();
//            userPraiseRecordVO.setResourceUid(item.getUid());
//            userPraiseRecordVO.setResourceType(ResourceTypeEnum.MOMENT.getType());
//            Map<String, Object> praiseMap = userPraiseRecordService.praisedCount(userPraiseRecordVO);
//            item.setPraiseInfo(praiseMap);
//
//            // 设置收藏相关信息
//            CollectDto collectVO = new CollectDto();
//            collectVO.setBizUid(item.getUid());
//            collectVO.setCollectType(ResourceTypeEnum.MOMENT.getType());
//            Map<String, Object> collectInfo = collectService.getCollectCount(collectVO);
//            item.setCollectInfo(collectInfo);
        }
        momentDtoPage.setRecords(list);
        return momentDtoPage;
    }

    /**
     * 查询动态排行榜
     *
     * @return
     */
    @Override
    public List<UserMomentEntity> getLeaderMoment(Boolean refresh) {
        String rankMomentListJson = redisUtil.get(RedisConf.TOP_LIST + Constants.SYMBOL_COLON + RedisConf.TOP_MOMENT_LIST);
        List<UserMomentEntity> leaders;
        if (StringUtils.isNotEmpty(rankMomentListJson) && refresh) {
            leaders = JsonUtils.jsonToList(rankMomentListJson, UserMomentEntity.class);
        } else {
            QueryWrapper<UserMomentEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("create_user_uid, count(uid) as sumCredits ");
            queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
            queryWrapper.eq(SQLConf.IS_PUBLISH, StatusEnum.ENABLE);
            queryWrapper.isNotNull(SQLConf.CREATE_USER_UID);
            queryWrapper.groupBy(SQLConf.CREATE_USER_UID);
            queryWrapper.orderByDesc(SQLConf.SUM_CREDITS);
            queryWrapper.last("limit 10");
            leaders = userMomentService.list(queryWrapper);
            List<String> userIds = new ArrayList<>();
            leaders.forEach((item) -> {
                userIds.add(item.getCreateUserUid());
            });

            // 获取用户列表
            Map<String, UserDto> userMap = this.usersConvert(userIds);
            leaders.forEach((item) -> {
                item.setUser(userMap.get(item.getCreateUserUid()));
            });
            redisUtil.setEx(RedisConf.TOP_LIST + Constants.SYMBOL_COLON + RedisConf.TOP_MOMENT_LIST, JsonUtils.objectToJson(leaders), 10, TimeUnit.MINUTES);
        }
        return leaders;
    }

    /**
     * 根据id获取用户动态
     *
     * @param uid
     * @return
     */
    @Override
    public UserMomentEntity getUserMomentById(String uid) {
        return this.getOne(
                new LambdaQueryWrapper<UserMomentEntity>()
                        .eq(UserMomentEntity::getUid, uid)
                        .eq(UserMomentEntity::getStatus, StatusEnum.ENABLE)
        );
    }

    /**
     * 用户动态下架
     *
     * @param uid
     * @return
     */
    @Override
    public Boolean revocationMoment(String uid) {
        return userMomentDao.revocationMoment(uid, "因举报过多暂时下架", AuditStatusEnum.REJECT);

    }

    @Override
    public Integer getUserMomentCount(String userUid) {
        QueryWrapper<UserMomentEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userUid)) {
            queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        }
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer momentCount = userMomentService.count(queryWrapper);
        return momentCount;
    }

    // endregion
    /***************************** web:end **************************/

    private UserDto convertUser(UserDto item) {
        UserDto user = new UserDto();
        user.setUid(item.getUid());
        user.setAvatar(item.getAvatar());
        user.setPhotoUrl(item.getPhotoUrl());
        user.setNickname(item.getNickname());
        user.setOccupation(item.getOccupation());
        user.setSummary(item.getSummary());
        user.setCreateTime(item.getCreateTime());
        user.setLoadingValid(item.getLoadingValid());
        user.setStatus(item.getStatus());
        user.setGender(item.getGender());
        user.setUserTag(item.getUserTag());
        user.setCredits(item.getCredits());
        user.setExpValue(item.getExpValue());
        user.setUserLevel(UserLevelEnum.getLvByExpValue(item.getExpValue()).getLevel());
        user.setBackgroundFileUrl(item.getBackgroundFileUrl());
        user.setBackgroundFileUid(item.getBackgroundFileUid());

        // 过滤用户
        String ip = item.getLastLoginIp();
        String ipPossession = redisUtil.get(RedisConf.USER_IP_POSSESSION + Constants.SYMBOL_COLON + user.getUid());
        if (StringUtils.isEmpty(ipPossession) && StringUtils.isNotEmpty(ip)) {
            // ip属地
            ipPossession = IpUtils.getIpPossession(ip);
            // 将信息设置到redis中
            redisUtil.setEx(RedisConf.USER_IP_POSSESSION + Constants.SYMBOL_COLON + user.getUid(), ipPossession, 1, TimeUnit.HOURS);
        }
        user.setUserIpPossession(ipPossession);
        return user;
    }


    /**
     * 设置用户头像, 批量方法
     *
     * @param list
     */
    private void setUserAvatar(List<UserDto> list) {
        List<String> fileUidList = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileUidList.add(item.getAvatar());
            }
            if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                fileUidList.add(item.getBackgroundFileUid());
            }
        });
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

    }

    @Override
    public Integer getUserMomentCount(UserMomentDto userMomentDto) {
        QueryWrapper<UserMomentEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userMomentDto.getCreateUserUid())) {
            queryWrapper.eq(SQLConf.CREATE_USER_UID, userMomentDto.getCreateUserUid());
        }
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer momentCount = userMomentService.count(queryWrapper);
        return momentCount;
    }

    /**
     * 根据用户id查询动态数
     *
     * @param userUids
     * @return
     */
    @Override
    public List<Map<String, String>> getUserMomentCountByUserIds(List<String> userUids) {
        return userMomentDao.getUserMomentCountByUserIds(userUids);
    }

    /**
     * 根据id集合查询用户动态
     *
     * @param uidList
     * @return
     */
    @Override
    public List<UserMomentEntity> listUserMomentByUidList(List<String> uidList) {
        return this.listByIds(uidList);
    }

    /**
     * 根据条件查询用户动态
     *
     * @param page
     * @param queryObject
     * @return
     */
    @Override
    public IPage<UserMomentEntity> queryPage(Page<UserMomentEntity> page, UserMomentDto queryObject) {
        Page<UserMomentEntity> pageList = userMomentDao.queryPage(page, queryObject);
        return pageList;
    }

    /**
     * List<userIds> 转换为 Map<userId , UserDto>
     *
     * @param userIds
     * @return
     */
    private Map<String, UserDto> usersConvert(List<String> userIds) {
        Map<String, UserDto> userMap = new HashMap<>();
        if (userIds.size() > 0) {
            R userResult = userFeignClient.listUserByUids(userIds);
            List<UserDto> userDtoList;
            if (userResult.getCode() == 0) {
                userDtoList = userResult.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
            }

            // 设置头像
            userUtil.setUserAvatar(userDtoList);
            // 过滤敏感信息
            List<UserDto> userList = userUtil.convertUserList(userDtoList);
            for (UserDto user : userList) {
                userMap.put(user.getUid(), user);
            }
        }
        return userMap;
    }

}